package com.magnate.software.spring.boot.web.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.magnate.software.common.mybatis.domain.DynamicDataSource;
import com.magnate.software.common.mybatis.interceptor.DialectResultSetHandlerInterceptor;
import com.magnate.software.common.mybatis.interceptor.DialectStatementHandlerInterceptor;
import com.magnate.software.spring.boot.web.handler.CodeTypeHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.TypeHandler;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * MyBatis配置
 *
 * @author WangYang
 * @version 1.0
 * @datetime 2017/3/1 19:19
 */
@Configuration
@EnableTransactionManagement
//@MapperScan(basePackages = {"com.magnate.software.spring.boot.web.mapper"}, sqlSessionFactoryRef = "sqlSessionFactory")
public class MyBatisConfig {

    @Primary
    @Bean("cmsDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.cms")
    public DataSource cmsDataSource() {
        return new DruidDataSource();
    }

    @Bean("tagsDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.tags")
    public DataSource tagsDataSource() {
        return new DruidDataSource();
    }

    @Bean("dataSource")
    public DataSource dataSource(@Qualifier("cmsDataSource") DataSource cmsDataSource,
                                 @Qualifier("tagsDataSource") DataSource tagsDataSource) {
        DynamicDataSource dataSource = new DynamicDataSource();
        Map<Object, Object> dataSourceMap = new HashMap<>();
        dataSourceMap.put("cms", cmsDataSource);
        dataSourceMap.put("tags", tagsDataSource);
        dataSource.setTargetDataSources(dataSourceMap);
        dataSource.setDefaultTargetDataSource(cmsDataSource);
        return dataSource;
    }

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        mapperScannerConfigurer.setBasePackage("com.magnate.software.spring.boot.web.mapper");
        return mapperScannerConfigurer;
    }

    @Bean("transactionManager")
    public PlatformTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        factoryBean.setDataSource(dataSource);
        factoryBean.setMapperLocations(resolver.getResources("classpath:/mapper/*/*.xml"));
        factoryBean.setTypeAliasesPackage("com.magnate.software.spring.boot.web.domain");
        // 翻页插件设置
        Interceptor[] plugins = new Interceptor[2];
        plugins[0] = new DialectStatementHandlerInterceptor();
        plugins[1] = new DialectResultSetHandlerInterceptor();
        factoryBean.setPlugins(plugins);
        // 注册自定类型处理器
        TypeHandler[] typeHandlers = new TypeHandler[1];
        typeHandlers[0] = new CodeTypeHandler();
        factoryBean.setTypeHandlers(typeHandlers);

        return factoryBean.getObject();
    }
}
